package com.gitee.wsl.ext.array

import kotlin.random.Random

inline fun <reified T> Array<T>.shuffle(generator: Random = Random): Array<T> {
    return apply {
        for (i in size downTo 2)
            swap(i - 1, generator.nextInt(i))
    }
}

/**
 * Simple Durstenfeld shuffle.
 * This will shuffle given array and will not make a copy, so beware.
 *
 *
 * See: [Yates_shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm)
 *
 *
 *
 * **Analysis**
 *
 *  * Time Complexity: `O(n)`
 *  * Space Complexity: `O(1)`
 *  * Alters Parameters: `true`
 *
 *
 *
 * @param array  to shuffle
 * @param random used to derive entropy - use [Random] instance if you want this to be secure
 */
fun ByteArray.shuffle(random: Random) {
    for (i in size - 1 downTo 1) {
        val index: Int = random.nextInt(i + 1)
        val a = this[index]
        this[index] = this[i]
        this[i] = a
    }
}